package com.young.ysepay.service.impl;

import com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
import com.young.ysepay.connector.SysconfigFeign;
import com.young.ysepay.constants.RefundConstants;
import com.young.ysepay.dao.YsRefundReceiptDao;
import com.young.ysepay.domain.YsRefundReceiptDO;
import com.young.ysepay.dto.YsPayDTO;
import com.young.ysepay.service.*;
import com.young.ysepay.utils.DateFormatHelper;
import com.young.ysepay.utils.Https;
import com.young.ysepay.utils.JSONUtils;
import com.young.ysepay.utils.UuidUtils;
import com.young.ysepay.utils.apiresult.ApiResult;
import com.young.ysepay.utils.apiresult.ApiResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.rmi.ServerException;
import java.text.SimpleDateFormat;
import java.util.*;


@Service
public class YsRefundRequestparamServiceImpl implements YsRefundRequestparamService {

	@Autowired
	YsRefundReceiptDao ysRefundReceiptDao;
	private static Logger logger = LoggerFactory.getLogger(YsRefundRequestparamServiceImpl.class);
	@Autowired
    YsBusinessPramService ysBusinessPramService;
	@Autowired
    YsBuildRequestParaService ysBuildRequestParaService;
	@Autowired
    YsVerifyJsonSignService ysVerifyJsonSignService;
	@Autowired
	SysconfigFeign sysconfigFeign;
	@Autowired
	private YsSplitRequestService ysSplitRequestService;
	@Override
    @Transactional(rollbackFor = Exception.class)
	public ApiResult ysRoutingRefundRequest(Map<String, Object> paraMap)  {

		Map<String, Object> map = null;
		//校验参数
        int sum =0;
        try {
		Boolean bo = verifyRoutingRefund(paraMap);
			logger.info("YsRefundServiceImpl-->ysRoutingRefundRequest params:" + JSON.toJSONString(paraMap));
            if (!bo) {
                logger.info("请求参数为空");
                return ApiResult.failure(ApiResultCode.FAILURE,paraMap.toString());
            }
			//查询预分账状态
			Map<String, Object> param = new HashMap<>();
			Map<String, Object> biz_contentMap = new HashMap<>();
			//获取订单号
			String outTradeNos = paraMap.get("out_trade_no").toString();
			biz_contentMap.put("out_trade_no", outTradeNos);
			biz_contentMap.put("src_usercode", sysconfigFeign.getPayeeUsercode());
			param.put("biz_content", JSON.toJSONString(biz_contentMap));
			logger.error("退款流程--查询分账状态param"+param);
			String queryResult = ysSplitRequestService.splitRequest(param);
			Map<String, Object> resultMap = JSONUtils.jsonToMap(queryResult);
			logger.error("退款流程--分账查询结果集"+resultMap.toString());
			String divisionStatusCode = resultMap.get("division_status_code").toString();
			if(!divisionStatusCode.equals("00")&& !divisionStatusCode.equals("02")){
				return ApiResult.failure(ApiResultCode.FAILURE,"当前分账未成功，请稍后重试！");
			}
			//拼接业务参数并获取银盛接口：
			map = routingJointVerifyParam(paraMap);
            YsRefundReceiptDO ysRefundReceiptDO = new YsRefundReceiptDO();
			//获取返回结果集
			if (null != map && map.get("code").equals("10000")) {
				BigDecimal refund_amount = (BigDecimal) map.get("refund_amount");
				String tradeNo = (String) map.get("trade_no");
				String outTradeNo = (String) map.get("out_trade_no");
				String accountDate = (String) map.get("account_date");
                String msg = (String) map.get("msg");
				ysRefundReceiptDO.setRefundAmount(refund_amount);
                ysRefundReceiptDO.setRefundMsg(msg);
                ysRefundReceiptDO.setRefundCode(map.get("code").toString());
				ysRefundReceiptDO.setTradeNo(tradeNo);
				ysRefundReceiptDO.setOutTradeNo(outTradeNo);
				ysRefundReceiptDO.setAccountDate(accountDate);
				ysRefundReceiptDO.setGmtCreate(new Date());
				ysRefundReceiptDO.setIsDelete(RefundConstants.COMMON_FLAG_UNDEL);
				ysRefundReceiptDO.setRefundType(RefundConstants.ROUTING_REFUND);
				int saveint = ysRefundReceiptDao.save(ysRefundReceiptDO);
				logger.error("YsRefundServiceImpl------------saveReceipt 保存数据为" + ysRefundReceiptDO.toString());
				if(saveint>0){
					return ApiResult.success();
				}
			}else{
			    //获取银盛回执错误消息
                String sub_code = (String) map.get("sub_code");
                String sub_msg = (String) map.get("sub_msg");
                //截取商户订单号
				String out_trade_no = (String) paraMap.get("out_trade_no");
				ysRefundReceiptDO.setRefundType(RefundConstants.ROUTING_REFUND);
                ysRefundReceiptDO.setOutTradeNo(out_trade_no);
                ysRefundReceiptDO.setRefundMsg(sub_msg);
                ysRefundReceiptDO.setRefundCode(sub_code);
                ysRefundReceiptDO.setGmtCreate(new Date());
                ysRefundReceiptDO.setIsDelete("1");
                ysRefundReceiptDao.save(ysRefundReceiptDO);
                logger.error("YsRefundServiceImpl------------saveReceipt 保存错误数据" + ysRefundReceiptDO.toString());
			}
		} catch (Exception e1) {
			logger.error("YsRefundServiceImpl-->ysRoutingRefundRequest fail e:{}", e1.getMessage());
            return ApiResult.failure(ApiResultCode.FAILURE);
		}
		return ApiResult.failure();
	}
	//校验分账退款参数
	public Boolean verifyRoutingRefund(Map<String, Object> paraMap) {
        Object temp = "";
		if (paraMap.isEmpty()) {
			logger.info("请求参数为空");
			return false;
		}else {
			//商户生成的订单号
			temp = paraMap.get("out_trade_no");
			String outTradeNo = temp!= null ? temp.toString():null;
            //需要退款的金额
            temp = paraMap.get("refund_amount");
            String refundAmount = temp!= null ? temp.toString():null;
			//退款的原因说明
            temp = paraMap.get("refund_reason");
            String refundReason = temp!= null ? temp.toString():null;
            //商戶ID
			temp = paraMap.get("storeId");
			String storeId = temp!= null ? temp.toString():null;
			//商戶金額
			temp = paraMap.get("storeAmount");
			String storeAmount = temp!= null ? temp.toString():null;
			//平台金额
			temp = paraMap.get("plantformAmount");
			String plantformAmount = temp!= null ? temp.toString():null;

			if (StringUtils.isEmpty(refundAmount)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 退款金额为" + refundAmount);
				return false;
			}
			if (StringUtils.isEmpty(refundReason)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 退款说明为" + refundReason);
				return false;
			}
			if (StringUtils.isEmpty(storeId)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 商户ID为" + storeId);
				return false;
			}
			if (StringUtils.isEmpty(outTradeNo)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 商户訂單号" + outTradeNo);
				return false;
			}
			if (StringUtils.isEmpty(storeAmount)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 商户金额为" + storeAmount);
				return false;
			}
			if (StringUtils.isEmpty(plantformAmount)) {
				logger.info("YsRefundServiceImpl-->verifyRoutingRefund params 平台金额为" + plantformAmount);
				return false;
			}
		}
		return true;
	}
    //封装银盛验证需要的参数
    public Map<String,Object> jointMap(Map<String, Object> paraMap){
        Map<String, Object> jointMap = new HashMap<>();
        String outTradeNo = (String) paraMap.get("out_trade_no");
        String tradeNo = (String) paraMap.get("trade_no");
        //需要退款金額
        String refundAmount = (String) paraMap.get("refund_amount");
        String refundReason = (String) paraMap.get("refund_reason");
        String storeId = (String) paraMap.get("storeId");
        String storeAmount = (String) paraMap.get("storeAmount");
        String plantformAmount = (String) paraMap.get("plantformAmount");
        //
		String virtualAmount =(String) paraMap.get("virtualAmount");
		//封装orderDivList原订单交易分帐信息
        List<Map<String,Object>> orderDivList = new ArrayList<>();
        //商户分账退款商户号、商户分账退款金额
      /*  Map<String, Object> storeMap = new HashMap<>();
        storeMap.put("division_mer_id",storeId);
        storeMap.put("is_charge_fee","02");*/

        if(new BigDecimal(plantformAmount).setScale(2, RoundingMode.HALF_UP).compareTo(BigDecimal.ZERO)==0.00){
			//商户分账退款商户号、商户分账退款金额
			if(new BigDecimal(virtualAmount).setScale(2, RoundingMode.HALF_UP).compareTo(BigDecimal.ZERO)==0.00){
				Map<String, Object> storeMap = new HashMap<>();
				storeMap.put("division_mer_id",storeId);
				storeMap.put("is_charge_fee","02");
				orderDivList.add(storeMap);
			}else {
				Map<String, Object> storeMap = new HashMap<>();
				storeMap.put("division_mer_id",storeId);
				storeMap.put("is_charge_fee","02");
				//营销账户
				Map<String, Object> virtualMap = new HashMap<>();
				virtualMap.put("division_mer_id",sysconfigFeign.getYSgymarketing());
				virtualMap.put("is_charge_fee","01");
				orderDivList.add(storeMap);
				orderDivList.add(virtualMap);
			}

		}else {
        	if(new BigDecimal(virtualAmount).setScale(2, RoundingMode.HALF_UP).compareTo(BigDecimal.ZERO)==0.00){
				//商户分账退款商户号、商户分账退款金额
				Map<String, Object> storeMap = new HashMap<>();
				storeMap.put("division_mer_id",storeId);
				storeMap.put("is_charge_fee","02");
				//平台分账退款商户号、平台分账退款金额
				Map<String, Object> platformMap = new HashMap<>();
				platformMap.put("division_mer_id",sysconfigFeign.getYSPlanformCode());
				platformMap.put("is_charge_fee","01");
				orderDivList.add(storeMap);
				orderDivList.add(platformMap);
			}else {
        		//营销账号
				Map<String, Object> virtualMap = new HashMap<>();
				virtualMap.put("division_mer_id",sysconfigFeign.getYSgymarketing());
				virtualMap.put("is_charge_fee","01");
				//商户分账退款商户号、商户分账退款金额
				Map<String, Object> storeMap = new HashMap<>();
				storeMap.put("division_mer_id",storeId);
				storeMap.put("is_charge_fee","02");
				//平台分账退款商户号、平台分账退款金额
				Map<String, Object> platformMap = new HashMap<>();
				platformMap.put("division_mer_id",sysconfigFeign.getYSPlanformCode());
				platformMap.put("is_charge_fee","02");
				orderDivList.add(storeMap);
				orderDivList.add(platformMap);
				orderDivList.add(virtualMap);
			}

		}
		////封装refundSplitInfo分账明细 分为平台与商户，分账退款金额总和等于退款金额，当原交易参与分账时，该参数必传，原交易不参与分账，该参数无值
		//商户
		Map<String, Object> refundSplitInfoStoreMap = new HashMap<>();
		refundSplitInfoStoreMap.put("refund_mer_id",storeId);
		refundSplitInfoStoreMap.put("refund_amount",(new BigDecimal(storeAmount).setScale(2,RoundingMode.HALF_UP)).toString());

		//平台
		Map<String, Object> refundSplitInfoplatformMap = new HashMap<>();
		refundSplitInfoplatformMap.put("refund_mer_id",sysconfigFeign.getYSPlanformCode());
		refundSplitInfoplatformMap.put("refund_amount",(new BigDecimal(plantformAmount).setScale(2,RoundingMode.HALF_UP)).toString());
		//营销
		Map<String, Object> refundSplitInfoVirtualMap = new HashMap<>();
		refundSplitInfoVirtualMap.put("refund_mer_id",sysconfigFeign.getYSgymarketing());
		refundSplitInfoVirtualMap.put("refund_amount",(new BigDecimal(virtualAmount).setScale(2,RoundingMode.HALF_UP)).toString());
		List<Map<String,Object>> refundSplitInfo = new ArrayList<>();
		if((new BigDecimal(plantformAmount).setScale(2,RoundingMode.HALF_UP)).compareTo(BigDecimal.ZERO) == 0.00){
			if(new BigDecimal(virtualAmount).setScale(2, RoundingMode.HALF_UP).compareTo(BigDecimal.ZERO)==0.00){
				refundSplitInfo.add(refundSplitInfoStoreMap);
			}else {
				//营销
				refundSplitInfo.add(refundSplitInfoVirtualMap);
				refundSplitInfo.add(refundSplitInfoStoreMap);
			}

		}else {
			if(new BigDecimal(virtualAmount).setScale(2, RoundingMode.HALF_UP).compareTo(BigDecimal.ZERO)==0.00){
				refundSplitInfo.add(refundSplitInfoStoreMap);
				refundSplitInfo.add(refundSplitInfoplatformMap);
			}else{
				refundSplitInfo.add(refundSplitInfoStoreMap);
				//平台
				refundSplitInfo.add(refundSplitInfoplatformMap);
				//营销
				refundSplitInfo.add(refundSplitInfoVirtualMap);
			}

		}
		//获取当前时间并转化格式
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		String shopdate = format.format(new Date());
		//根据银盛规则"RD"+当前时间+随机5位数 生成唯一请求标示
		String outRequestNo = "RD"+shopdate+ UuidUtils.getUuid(5);
		//封装Map
		jointMap.put("out_trade_no",outTradeNo);
		jointMap.put("refund_amount",(new BigDecimal(refundAmount).setScale(2,RoundingMode.HALF_UP)).toString());
		jointMap.put("refund_reason",refundReason);
		jointMap.put("order_div_list",orderDivList);
		jointMap.put("refund_split_info",refundSplitInfo);
		jointMap.put("shopdate",shopdate);
		jointMap.put("out_request_no",outRequestNo);
        return jointMap;
    }

	//拼接业务参数并校验签名验证
	public Map<String, Object> routingJointVerifyParam(Map<String, Object> paraMap) throws Exception {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        Map<String, Object> bizMap = new HashMap<>();
        YsPayDTO ysPayDTO = ysBusinessPramService.ysBusinessPram();

		//获取参数封装map集合
		Map<String, Object> map = jointMap(paraMap);
		//获取商户订单号
		String out_trade_no = map.get("out_trade_no").toString();
		//获取分账需要退款的金额
        //Object refund_amount1 = map.get("refund_amount");
        String refund_amount = (String) map.get("refund_amount");
		//获取退款说明
		String refund_reason = map.get("refund_reason").toString();
		//原订单交易分帐信息
		List<Map<String,Object>> order_div_list = (List<Map<String, Object>>) map.get("order_div_list");
		//分账明细，分账退款金额总和等于退款金额
		List<Map<String,Object>> refund_split_info = (List<Map<String, Object>>) map.get("refund_split_info");
		//商户日期
		String shopdate = map.get("shopdate").toString();
		//退款请求标识
		String out_request_no = map.get("out_request_no").toString();

		bizMap.put("out_trade_no",out_trade_no);
		bizMap.put("refund_amount",(new BigDecimal(refund_amount).setScale(2,RoundingMode.HALF_UP)).toString());
		bizMap.put("refund_reason",refund_reason);
		bizMap.put("order_div_list",order_div_list);
		bizMap.put("refund_split_info",refund_split_info);
		bizMap.put("shopdate",shopdate);
		bizMap.put("out_request_no",out_request_no);

		//公共参数
		Map<String, String> commonMap = new HashMap<>();
		commonMap.put("method", "ysepay.online.trade.refund.split");
		commonMap.put("partner_id", ysPayDTO.getPARTNER_ID());
		commonMap.put("timestamp", DateFormatHelper.getNowTimeStr());
		commonMap.put("charset", ysPayDTO.getDEFAULT_CHARSET());
		commonMap.put("sign_type", ysPayDTO.getSIGN_ALGORITHM());
		commonMap.put("version", ysPayDTO.getVERSION());
		commonMap.put("biz_content", JSON.toJSONString(bizMap));
        Map<String, Object> returnMap = null;
        try {
		Map<String, String> sParaMap = ysBuildRequestParaService.buildRequestPara(commonMap);
		String returns = Https.httpsSend(ysPayDTO.getYSEPAY_GATEWAY_URL(), sParaMap);
		resultMap = (Map) JSON.parse(returns);
		logger.error("调用银盛分账退款返回值"+resultMap);
		Object obj = resultMap.get("ysepay_online_trade_refund_split_response");
		boolean verifyResult = false;
		if(obj != null){
			int yscount = returns.toString().indexOf("ysepay_online_trade_refund_split_response");
			String str = returns.substring(yscount);
			str = str.replace("ysepay_online_trade_refund_split_response", "");
			str = str.substring(2, str.length() - 1);
			verifyResult = ysVerifyJsonSignService.verifyJsonSign(resultMap.get("sign").toString(), str, "utf-8");
			logger.info("YsRefundServiceImpl -------------------routingJointVerifyParam"+"校验是否成功"+verifyResult+resultMap);
			returnMap = JSONUtils.jsonToMap(str);
			return returnMap;
		}
        } catch (IOException e) {
            logger.error("银盛分账退款接口"+e.getMessage());
            e.printStackTrace();
        } catch (IllegalAccessException e1) {
            logger.error("银盛分账退款接口"+e1.getMessage());
            e1.printStackTrace();
        } catch (Exception e) {
            logger.error("银盛分账退款接口"+e.getMessage());
            e.printStackTrace();
        } finally {
            return returnMap;
        }
	}

}
